package com.wenx.completablefuture;

import java.util.Random;
import java.util.concurrent.*;

/**
 * 商店类
 */
public class Shop {

    private String name;

    public Shop() {
    }

    public Shop(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    //模拟 1秒钟延迟的方法
    public void delay() {
        try {
            Thread.sleep(1000L);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    private static final Random random = new Random();
    //一个模拟生成0.5秒至2.5秒随机延迟的方法
    public static void randomDelay() {
        int delay = 500 + random.nextInt(2000);
        try {
            Thread.sleep(delay);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    //在getPrice方法中引入一个模拟的延迟
    public double getPrice(String product) {
        return calculatePrice(product);
    }

    //在getPrice方法中引入一个模拟的延迟
    public String getPrice2(String product) {
        double price = calculatePrice(product);
        Discount.Code code = Discount.Code.values()[random.nextInt(Discount.Code.values().length)];
        return String.format("%s:%.2f:%s", product, price, code);
    }

    private double calculatePrice(String product) {
        delay();
        return random.nextDouble() * product.charAt(0) + product.charAt(1);
    }


    //异步调用
    public Future<Double> getPriceAsync(String product) {
        //创建CompletableFuture 对象，它会包含计算的结果
        CompletableFuture<Double> futurePrice = new CompletableFuture<>();
        //在另一个 线程中以 异步方式 执行计算
        new Thread(()->{
            try {
                double price = calculatePrice(product);
                //需长时间计算的任务结 束并得出结果时，设置 Future的返回值
                futurePrice.complete(price);
            } catch (Exception e) {
                //获取异常
                futurePrice.completeExceptionally(e);
            }
        }).start();
        //无需等待还没结束的计 算，直接返回Future对象
        return futurePrice;
    }

}
